using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using Dapper;

namespace hao_Common.Dapper.Query
{
    public static class QueryBuilderExtensions
    {
        /// <summary>
        /// 创建查询构建器
        /// </summary>
        public static IQueryBuilder<T> CreateQueryBuilder<T>(this IDbConnection connection, Expression<Func<T, bool>> whereExp = null)
        {
            var builder = new ExpressionQueryBuilder<T>();
            if (whereExp != null)
            {
                builder.Where(whereExp);
            }
            return builder;
        }
        
        /// <summary>
        /// 执行查询
        /// </summary>
        public static IEnumerable<T> Query<T>(this IDbConnection connection, IQueryBuilder<T> builder)
        {
            string sql = builder.GetQuery();
            return connection.Query<T>(sql, builder.Param);
        }
        
        /// <summary>
        /// 执行分页查询
        /// </summary>
        public static (IEnumerable<T> Data, int Total) QueryPaged<T>(this IDbConnection connection, IQueryBuilder<T> builder, int pageIndex, int pageSize)
        {
            // 获取总数
            string countSql = builder.GetCountQuery();
            int total = connection.QuerySingle<int>(countSql, builder.Param);
            
            // 获取分页数据
            string dataSql = $"{builder.GetQuery()} LIMIT {pageSize} OFFSET {pageIndex * pageSize}";
            var data = connection.Query<T>(dataSql, builder.Param);
            
            return (data, total);
        }
        
        /// <summary>
        /// 执行单个查询
        /// </summary>
        public static T QuerySingle<T>(this IDbConnection connection, IQueryBuilder<T> builder)
        {
            string sql = builder.GetQuery();
            return connection.QuerySingleOrDefault<T>(sql, builder.Param);
        }
        
        /// <summary>
        /// 检查是否存在
        /// </summary>
        public static bool Exists<T>(this IDbConnection connection, IQueryBuilder<T> builder)
        {
            string sql = $"SELECT CASE WHEN EXISTS({builder.GetQuery()}) THEN 1 ELSE 0 END";
            return connection.QuerySingle<bool>(sql, builder.Param);
        }
        
        /// <summary>
        /// 获取数量
        /// </summary>
        public static int Count<T>(this IDbConnection connection, IQueryBuilder<T> builder)
        {
            string sql = builder.GetCountQuery();
            return connection.QuerySingle<int>(sql, builder.Param);
        }
    }
}